/*
 * @Author: 13177709051 3506463075@qq.com
 * @Date: 2024-11-05 22:11:16
 * @LastEditors: 13177709051 3506463075@qq.com
 * @LastEditTime: 2024-11-22 21:13:48
 * @FilePath: /linux31/udp_echo_server/InetAddr.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#pragma once

#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

class InetAddr
{
private:
    void ToHost(const struct sockaddr_in &addr)
    {
        _port = ntohs(addr.sin_port);
        // _ip = inet_ntoa(addr.sin_addr);
        char ip_buf[32];
        // inet_p to n
        // p: process
        // n: net
        // inet_pton(int af, const char *src, void *dst);
        // inet_pton(AF_INET, ip.c_str(), &addr.sin_addr.s_addr);
        ::inet_ntop(AF_INET, &addr.sin_addr, ip_buf, sizeof(ip_buf));
        _ip = ip_buf;
    }
    // std::string 类的赋值运算符（operator=）可以接受 const char* 类型的参数。当你将 ip_buf 赋给 _ip 时，std::string 会自动将这个 const char* 字符串转换成一个 std::string 对象。
    // std::string 会复制 char 数组中的内容，并保存在其内部的动态分配内存中。
public:
    InetAddr(const struct sockaddr_in &addr):_addr(addr)
    {
        ToHost(addr);
    }

    bool operator == (const InetAddr &addr)
    {
        return (this->_ip == addr._ip && this->_port == addr._port);
    }
    std::string Ip()
    {
        return _ip;
    }
    uint16_t Port()
    {
        return _port;
    }
    struct sockaddr_in Addr()
    {
        return _addr;
    }
    std::string AddrStr()
    {
        return _ip + ":" + std::to_string(_port);
    }
    ~InetAddr()
    {
    }

private:
    std::string _ip;
    uint16_t _port;
    struct sockaddr_in _addr;
};
// 这个代码定义了一个 InetAddr 类，主要用于处理与网络地址（IPv4地址和端口）相关的操作。
// InetAddr 类成员变量
// _ip：用于存储 IP 地址，以 std::string 类型存储。
// _port：用于存储端口号，使用 uint16_t（16 位无符号整数）。
// _addr：存储 sockaddr_in 结构体，表示一个 IPv4 地址和端口。s
// 构造函数
// 构造函数接收一个 sockaddr_in 类型的地址（通常是通过 socket 操作获得的）。它将该地址保存到成员变量 _addr 中，并调用 ToHost 方法将其转换为可读的 IP 地址和端口。
// ToHost 方法
// ToHost 方法负责将 sockaddr_in 结构中的信息提取并转换为人类可读的形式：
// ntohs(addr.sin_port)：将网络字节序的端口号转换为主机字节序，并赋值给 _port。
// inet_ntop(AF_INET, &addr.sin_addr, ip_buf, sizeof(ip_buf))：将 IP 地址（addr.sin_addr）从网络字节序转换为点分十进制格式的字符串，并保存在 ip_buf 中。然后将该字符串赋给 _ip。
// inet_ntop 是一个用于将网络地址转换为文本字符串的标准函数。它与 inet_ntoa 类似，但是支持多种地址族（如 IPv6 和 IPv4），因此 inet_ntop 更加通用。
// 成员函数
// operator == (const InetAddr &addr)：重载了 == 操作符，用于比较两个 InetAddr 对象是否相等。相等的条件是它们的 IP 地址和端口号都相同。
// Ip()：返回 IP 地址的字符串表示。
// Port()：返回端口号（uint16_t 类型）。
// Addr()：返回 sockaddr_in 结构体，可以用于与底层 socket API 进行交互。
// AddrStr()：将 IP 地址和端口组合成一个字符串，例如 "192.168.1.1:8080"。
// 析构函数
// 析构函数为空，当前类没有动态分配资源，因此不需要做额外的清理工作。